package com.macro.mall.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.macro.mall.common.exception.ApiException;

import com.macro.mall.model.XhsUser;
import com.macro.mall.model.request.XhsPhoneDecryptRequest;
import com.macro.mall.model.response.XhsPhoneDecryptResponse;
import com.macro.mall.service.XhsPhoneService;
import com.macro.mall.service.XhsUserService;
import com.macro.mall.utils.XhsDataDecryptUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 小红书手机号服务实现
 */
@Service
@Slf4j
public class XhsPhoneServiceImpl implements XhsPhoneService {

    @Resource
    private XhsUserService xhsUserService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public XhsPhoneDecryptResponse decryptPhoneNumber(XhsPhoneDecryptRequest request, String sessionKey) throws Exception {
        // 1. 如果有签名则校验签名
        if (request.getRawData() != null && request.getSignature() != null) {
            if (!XhsDataDecryptUtil.checkSignature(request.getRawData(), request.getSignature(), sessionKey)) {
                log.error("签名校验失败");
                throw new ApiException("签名校验失败");
            }
        }

        // 2. 解密数据
        String decryptedData = decryptData(request.getEncryptedData(), sessionKey, request.getIv());

        // 3. 解析数据
        XhsPhoneDecryptResponse xhsPhoneDecryptResponse = parseDecryptedData(decryptedData);
        if (ObjectUtil.isNotEmpty(xhsPhoneDecryptResponse.getPhoneNumber())){
            XhsUser byOpenId = xhsUserService.getByOpenId(request.getOpenId());
            if (ObjectUtil.isEmpty(byOpenId)){
                XhsUser xhsUser = new XhsUser();
                xhsUser.setPhoneNumber(xhsPhoneDecryptResponse.getPhoneNumber());
                xhsUser.setOpenId(request.getOpenId());
                xhsUser.setCreateTime(new Date());
                xhsUser.setUpdateTime(new Date());
                xhsUserService.create(xhsUser);
            }else {
                if (!byOpenId.getPhoneNumber().equals(xhsPhoneDecryptResponse.getPhoneNumber())){
                    byOpenId.setPhoneNumber(xhsPhoneDecryptResponse.getPhoneNumber());
                    xhsUserService.update(byOpenId);
                }
            }


        }
return xhsPhoneDecryptResponse;
    }

    @Override
    public XhsPhoneDecryptResponse decryptPhoneNumberSimple(String encryptedData, String iv, String sessionKey) throws Exception {
        // 直接解密数据
        String decryptedData = decryptData(encryptedData, sessionKey, iv);
        return parseDecryptedData(decryptedData);
    }

    private String decryptData(String encryptedData, String sessionKey, String iv) throws Exception {
        try {
            return XhsDataDecryptUtil.decryptData(encryptedData, sessionKey, iv);
        } catch (Exception e) {
            log.error("解密手机号数据失败", e);
            throw new ApiException("解密手机号数据失败: " + e.getMessage());
        }
    }

    private XhsPhoneDecryptResponse parseDecryptedData(String decryptedData) throws Exception {
        try {
            DecryptedPhoneData data = objectMapper.readValue(decryptedData, DecryptedPhoneData.class);

            XhsPhoneDecryptResponse response = new XhsPhoneDecryptResponse();
            response.setPhoneNumber(data.getPhoneNumber());
            response.setPurePhoneNumber(data.getPurePhoneNumber());
            response.setCountryCode(data.getCountryCode());
            response.setAppId(data.getWatermark().getAppId());
            response.setTimestamp(data.getWatermark().getTimestamp());

            return response;
        } catch (Exception e) {
            log.error("解析解密数据失败", e);
            throw new ApiException("解析解密数据失败: " + e.getMessage());
        }
    }

    /**
     * 解密后的数据结构
     */
    @Data
    private static class DecryptedPhoneData {
        private String phoneNumber;
        private String purePhoneNumber;
        private String countryCode;
        private Watermark watermark;
    }

    @Data
    private static class Watermark {
        private String appId;
        private long timestamp;
    }
}
